//这是一个实现了部分面向对象功能的类，附加了事件功能
//Note: 多层次的继承将极具降低程序的运行效率
define(['./classEvent', './mixin'], function(EnableEvent, Mixin) {
  var NOP = function(){};
  var Base = NOP;

  //添加事件支持
  EnableEvent(Base);

  Base.prototype.initializer = function() {};

  Base.prototype._init = function(){
    this.callAllSuper('initializer');
    this.initializer();
  };

  Base.prototype.callSuper = function(funName, args){
    var self = this;
    var superFun = self.getSuperFun(funName);
    if(superFun){ 
      return superFun.call(self, args);
    }
  };

  Base.prototype.callAllSuper = function(funName, args){
    var self     = this,
        _super   = self,
        superFun = NOP,
        funStack = [];

    while(_super && (superFun = _super.getSuperFun(funName))){
      funStack.push(superFun);
      superFun = self.getSuperFun(funName);
      _super = _super.__super;
    }

    while(superFun=funStack.pop()){
      superFun.call(self, args);
    }
  };

  Base.prototype.getSuperFun = function(funName){
    var thisProto = this.constructor.prototype;
    if(thisProto.__super &&
       thisProto.__super &&
       thisProto.__super[funName]){
      return thisProto.__super[funName];
    } else {
      return null;
    }
  };

  Base.prototype.get = function(key) {
    if (this.__attrs[key]) {
      if (this.__attrs[key].get) {
        return this.__attrs[key].get.apply(this, arguments);
        //return this.__attrs[key].get(key);
      } else {
        return this.__attrs[key].value;
      }
    }
  };

  //允许链式调用
  Base.prototype.set = function(key, value) {
    if (this.__attrs[key] !== undefined) {
      var oldVal = this.get(key);
      if (this.__attrs[key].set) {
        this.__attrs[key].value = this.__attrs[key].set.apply(this, [value]);
      } else {
        this.__attrs[key].value = value;
      }
      this.fire('afterChange:'+key, {
        oldVal:oldVal,
        newVal:this.get(key)
      });
    }
    return this;
  };

  Base.prototype.constructor = Base;

  Base.extend = function(functions, attributes) {
    var self = this;
    var superConstructor = this.prototype.constructor;

    /**
     * 一个子类的构造函数
     * @param {Object} config 指定属性
     * @param {Boolean} noInit 是否放弃初始化新创建的对象 
     * */
    var newClass = function(config, noInit) {
      this._initEvent();

      if(!this.hasOwnProperty('__attrs')){
        this.__attrs = {};
      }

      superConstructor.apply(this, [config, true]);
      
      Mixin(this.__attrs, attributes, 1);

      if(noInit)return;

      for (var arg in config) {
        this.set(arg, config[arg]);
      }

      this._init();
    };

    //下面这种做法会造成prototype混乱，子类在修改prototype的时候会影响父类
    //newClass.prototype = this.prototype;
    //下面这种做法会打乱类的初始化顺序
    //newClass.prototype = new this.prototype.constructor();

    newClass.prototype = new this.prototype.constructor({}, true);
    newClass.prototype.__super = this.prototype;
    newClass.prototype.constructor = newClass;
    newClass.extend = this.extend;
    Mixin(newClass.prototype, functions);

    return newClass;
  };

  return Base;
});

